package com.yanfan.common.utils;

import com.alibaba.fastjson2.JSON;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


/**
 * 操作系统的工具类
 */
public class OSUtils {

    /**
     * 获取window or linux机器码
     *
     * @return
     */
    public static String getOSNumber() {
        Map<String, Object> codeMap = new HashMap<>(2);
        String result = "";
        if (isWindows()) {
            String processorId = getCPUSerialNumber();
            codeMap.put("pid", processorId);
            String serialNumber = getHardDiskSerialNumber();
            codeMap.put("snm", serialNumber);
            String codeMapStr = JSON.toJSONString(codeMap);
            String serials = Md5Utils.md5(codeMapStr);
            result = getSplitString(serials, "-", 8);
        } else {
            codeMap.put("hmi", getHostMachineId());
            codeMap.put("nwi", getContainerNetworkId());
            String codeMapStr = JSON.toJSONString(codeMap);
            String serials = Md5Utils.md5(codeMapStr);
            result = getSplitString(serials, "-", 8);
        }
        return result;
    }

    /**
     * 获取CPU序列号
     *
     * @return
     * @throws IOException
     */
    public static String getCPUSerialNumber() {
        String next;
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"wmic", "cpu", "get", "ProcessorId"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String serial = sc.next();
            next = sc.next();
        } catch (IOException e) {
            throw new RuntimeException("获取CPU序列号失败");
        }
        return next;
    }

    /**
     * 获取 硬盘序列号(Windows)
     *
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public static String getHardDiskSerialNumber() {
        try {
            Process process = Runtime.getRuntime().exec(new String[]{"wmic", "path", "win32_physicalmedia", "get", "serialnumber"});
            process.getOutputStream().close();
            Scanner sc = new Scanner(process.getInputStream());
            String serial = sc.next();
            return sc.next();
        } catch (IOException e) {
            throw new RuntimeException("获取硬盘序列号失败");
        }
    }

    /**
     * bois版本号(linux)
     *
     * @return
     */
    public static String getBoisVersion() {
        String result = "";
        Process p;
        try {
            // 管道
            p = Runtime.getRuntime().exec("sudo dmidecode -s bios-version");
            BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String line;
            while ((line = br.readLine()) != null) {
                result += line;
                break;
            }
            br.close();
        } catch (IOException e) {
            System.out.println("获取主板信息错误");
        }
        return result;
    }

    /**
     * 获取系统序列号(linux)
     *
     * @return
     */
    public static String getHostMachineId() {
        try {
            Path path = Paths.get("/etc/machine-id");
            if (Files.exists(path)) {
                String content = new String(Files.readAllBytes(path));
                if (!content.isEmpty()) {
                    return content;
                }
            }
        } catch (Exception e) {
            System.out.println("获取序列号失败: " + e.getMessage());
        }
        return "unknown_host_id";
    }

    public static String getContainerNetworkId() {
        String interfaceName = "eth0"; // 默认网卡名称（可配置化）
        try {
            Path addressPath = Paths.get("/sys/class/net/" + interfaceName + "/address");
            if (Files.exists(addressPath)) {
                String mac = new String(Files.readAllBytes(addressPath));
                return mac.replace(":", ""); // 去除冒号，简化格式
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "unknown_mac";
    }


    private static String getSplitString(String str, String split, int length) {
        int len = str.length();
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < len; i++) {
            if (i % length == 0 && i > 0) {
                temp.append(split);
            }
            temp.append(str.charAt(i));
        }
        return temp.toString();
    }

    public static boolean isWindows() {
        return System.getProperty("os.name").toLowerCase().contains("windows");
    }
}
